
package com.be.beadmin.product.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.basicData.dto.output.UserEx;
import com.be.beadmin.basicData.entity.Role;
import com.be.beadmin.basicData.service.UserService;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.product.dto.WorkOrderProductPlanDto;
import com.be.beadmin.product.dto.input.*;
import com.be.beadmin.product.dto.output.*;
import com.be.beadmin.product.entity.*;
import com.be.beadmin.product.mapper.ProductManufactInforMapper;
import com.be.beadmin.product.mapper.ProductManufactInforMapperEx;
import com.be.beadmin.product.mapper.WrokingHoursDetailsMapper;
import com.be.beadmin.product.repository.*;
import com.be.beadmin.product.service.PlantCapacityCalendarService;
import com.be.beadmin.product.service.ProductManufactInforService;
import com.be.beadmin.product.service.UserWorkHourInfoService;
import com.be.beadmin.product.service.WorkOrderInforService;
import com.be.beadmin.product.task.UpdateTimeTask;
import com.be.beadmin.project.entity.BatchPlan;
import com.be.beadmin.project.entity.BatchProduct;
import com.be.beadmin.project.entity.PlanStage;
import com.be.beadmin.project.repository.BatchPlanRepository;
import com.be.beadmin.project.repository.BatchProductRepository;
import com.be.beadmin.project.repository.PlanStageRepository;
import com.be.beadmin.project.service.BatchPlanService;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.project.service.PlanStageService;
import com.be.beadmin.service.entity.FactoryCalendar;
import com.be.beadmin.service.repository.FactoryCalendarRepository;
import com.be.beadmin.service.service.DictDataService;
import com.be.beadmin.service.task.TaskThreadPool;
import com.be.beadmin.service.util.DateUtil;
import com.be.beadmin.service.util.NumberUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @description 服务实现
 * @date 2023-03-19
 **/
@Service
@RequiredArgsConstructor
public class ProductManufactInforServiceImpl implements ProductManufactInforService {

    @Autowired
    private ProductManufactInforRepository productManufactInforRepository;
    @Autowired
    private ProductManufactInforMapper productManufactInforMapper;
    @Autowired
    private ProductManufactInforMapperEx productManufactInforExMapper;

    @Autowired
    private BatchPlanRepository batchPlanRepository;

    @Autowired
    private DictDataService dictDataService;
    @Autowired
    private BatchPlanService batchPlanService;
    @Autowired
    private BatchProductRepository batchProductRepository;

    @Autowired
    private WrokingHoursDetailsRepository wrokingHoursDetailsRepository;
    @Autowired
    private WrokingHoursDetailsMapper wrokingHoursDetailsMapper;

    @Autowired
    private WrokingHoursOverViewRepository wrokingHoursOverViewRepository;
    @Autowired
    private FactoryCalendarRepository factoryCalendarRepository;
    @Autowired
    private PlantCapacityCalendarService plantCapacityCalendarService;
    @Autowired
    private UserWorkHourInfoService userWorkHourInfoService;

    @Autowired
    private UserWorkHourInfoRepository userWorkHourInfoRepository;
    @Autowired
    private WorkOrderInforService workOrderInforService;

    @Autowired
    private WorkOrderInforRepository workOrderInforRepository;


    @Autowired
    private TaskThreadPool taskThreadPool;
    @Autowired
    private PlanStageRepository planStageRepository;
    @Autowired
    private PlanStageService planStageService;
    @Autowired
    private InfoService infoService;

    @Autowired
    private UserService userService;

    @Override
    public Page<ProductManufactInforEx> getProductManufactInforByPage(PageEntity pageEntity) {
        List<String> batchProductIds = workOrderInforRepository.findbatchProductByReleaseFlagAndDelete(1, 0);

        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<ProductManufactInfor> page = productManufactInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(ProductManufactInfor_.delete), 0); //过滤为0
                    list.add(pre2);
//                        Predicate pre3 = criteriaBuilder.in(root.get(ProductManufactInfor_.delete), 0); //过滤为0

                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.asc(root.get(ProductManufactInfor_.sequence).as(Integer.class)),criteriaBuilder.desc(root.get(ProductManufactInfor_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<ProductManufactInforEx> page1 = page.map(productManufactInforExMapper::toEntity);
        return page1;

    }

    @Override
    public void addProductManufactInfor(ProductManufactInforDto productManufactInforDto) {
        ProductManufactInfor result = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("ProductManufactInfor不存在,请重新查询");
        }
        ProductManufactInfor productManufactInfor = productManufactInforMapper.toEntity(productManufactInforDto);
        productManufactInforRepository.save(productManufactInfor);
    }

    @Override
    public void updateProductManufactInfor(ProductManufactInforUpdateDto productManufactInforUpdateDto) {
//        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforById(productManufactInforUpdateDto.getId());
//        // 未查询到改计划信息
//        if (productManufactInfor == null) throw new BeadminException("未查询到改计划信息，无法修改，请检查后端！");
//        // 工序已经开始无法调整
//        if (productManufactInfor.getProcessStatus() != 0) throw new BeadminException("工序已经开始无法调整");
//        // 工序结束时间超过批次计划生产结束时间
//        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(productManufactInfor.getBatchProductId(), 0);
//        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
//        PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");
//        if (productManufactInforUpdateDto.getPlanManufactEndDate().after(stage.getStagePlanEndTime()))
//            throw new BeadminException("工序结束时间超过批次计划生产结束时间， 请不要超过" + new SimpleDateFormat("yyyy-MM-dd").format(stage.getStagePlanEndTime()));
//
//        // 存储
//        productManufactInfor.setPlanManufactStartDate(productManufactInforUpdateDto.getPlanManufactStartDate());
//        productManufactInfor.setPlanManufactEndDate(productManufactInforUpdateDto.getPlanManufactEndDate());
////            productManufactInfor = productManufactInforMapper.toEntity(productManufactInforDto);
//        productManufactInforRepository.save(productManufactInfor);
//
//        // 记录调整日志
//        // 并更新产能日历
//        plantCapacityCalendarService.updatePlantCapCalender(batchProduct, batchPlan);


    }


    @Override
    public void delProductManufactInfor(String id) {
        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforById(id);
        productManufactInfor.setDelete(1);
        productManufactInforRepository.save(productManufactInfor);
    }

    @Override
    public void delProductManufactInfors(List<String> ids) {
    }

    /**
     * 自动排程
     *
     * @param batchProductIds
     * @return
     */
    @Override
    public String autoScheduling(List<String> batchProductIds) {
        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByIdAndDelete("standard1", 0);
        if (batchProductIds.size() == 0) return "";
        List<BatchProduct> batchProducts = batchProductRepository.findBatchProductsByIdInAndDelete(batchProductIds, 0);
        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProducts.get(0).getBatchPlanId(), 0);
        System.out.println("batchPlan" + batchPlan.toString());
        Map<String,List<String>> map = new HashMap<>();
        for (BatchProduct bp : batchProducts) {
            // 直接查询时升序查询
            List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndProcessStatusNotAndDeleteOrderBySequenceAsc(bp.getProductCode(), 0, 0);
            if (productManufactInfors == null) {
                throw new BeadminException("还没有设计工艺路线！");
            }
            for (ProductManufactInfor p :
                    productManufactInfors) {
                System.out.println("p:" + p.toString());

            }


            //            // 列表升序排列
//            productManufactInfors.stream().sorted(Comparator.comparingInt(ProductManufactInfor::getSequence)).collect(Collectors.toList());
            // 最后一道个工序
            ProductManufactInfor productManufactInfor = productManufactInfors.get(productManufactInfors.size() - 1);
//            BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(bp.getBatchPlanId(), 0);
            PlanStage pickStage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产分料");
            PlanStage fitStage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");
            PlanStage packStage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "打包入库");
            // 倒推时间
            PlanStage deliverStage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "发货日期");



//            productManufactInfor.setPlanManufactStartDate(deliverStage.getStagePlanStartTime());
//            System.out.println("productManufactInfor.getPlanManufactStartDate():" + productManufactInfor.getPlanManufactStartDate());
//            productManufactInfor.setPlanManufactEndDate(deliverStage.getStagePlanEndTime());
//            System.out.println("productManufactInfor.getPlanManufactEndDate():" + productManufactInfor.getPlanManufactEndDate());
//
//
//            productManufactInforRepository.save(productManufactInfor);
            ProductManufactInfor afterProcess = productManufactInfor;
            List<String> processNames = new ArrayList<>();
            // 升序工序的时间
            for (int i = productManufactInfors.size() - 1; i >= 0; i--) {
                ProductManufactInfor pmi = productManufactInfors.get(i);
                // 最后一道工序
                if (i == productManufactInfors.size() - 1) {
                    // 最后一道工序 用发货时间
                    pmi.setPlanManufactEndDate(fitStage.getStagePlanEndTime());
                } else {
                    // 其余的用之前日期来表示
                    pmi.setPlanManufactEndDate(DateUtil.computeDate(afterProcess.getPlanManufactStartDate(),-1*24));
                }
                // 然后用标准周期推算出开始时间，  需要判断开始时间是否早于批次规定的开始时间。
                pmi.setPlanManufactStartDate(DateUtil.computeDate(pmi.getPlanManufactEndDate(), -24 * pmi.getStandCycle()));
                switch (pmi.getProcessName()) {
                    case "器件分料":
                        if (pmi.getPlanManufactStartDate().before(pickStage.getStagePlanStartTime())) {
                            // 如果开始时间小于批次设定的工序开始时间
                            pmi.setPlanManufactStartDate(pickStage.getStagePlanStartTime());
                            pmi.setPlanManufactEndDate(DateUtil.computeDate(pmi.getPlanManufactStartDate(), 24 * pmi.getStandCycle()));
                            processNames.add(pmi.getProcessName());
                        }
                        break;
                    case "装配":
                        if (pmi.getPlanManufactStartDate().before(fitStage.getStagePlanStartTime())) {
                            // 如果开始时间小于批次设定的工序开始时间
                            pmi.setPlanManufactStartDate(pickStage.getStagePlanStartTime());
                            processNames.add(pmi.getProcessName());
                        }

                        break;
                    case "打包":
                        if (pmi.getPlanManufactStartDate().before(packStage.getStagePlanStartTime())) {
                            // 如果开始时间小于批次设定的工序开始时间
                            pmi.setPlanManufactStartDate(pickStage.getStagePlanStartTime());
                            processNames.add(pmi.getProcessName());
                        }
                        break;
                }



                afterProcess = pmi;
                productManufactInforRepository.save(pmi);
                // 生成产能日历
                plantCapacityCalendarService.generateCapacityCalendar(pmi, bp, factoryCalendar, batchPlan);
            }
            map.put(bp.getProductCode(),processNames);
        }
        StringBuilder sb = new StringBuilder("自动排程结束 ");
        if (!map.isEmpty()){
            for (Map.Entry<String, List<String>> next : map.entrySet()) {
                sb.append("柜体：【").append(next.getKey()).append("】的工序【");
                for (String name : next.getValue()) {
                    sb.append(name).append(",");
                }
                sb.append("】的计划开始时间早于批次工序的开始时间，已修改为批次工序的开始时间");
                sb.append("\n");
            }

        }
        return sb.toString();
    }

    /**
     * 分页的查询生产排程
     *
     * @param pageEntity
     * @return
     */
    @Override
    public Page<Object> getProductManufactByPage(HttpServletRequest request, PageEntity pageEntity) {
//        Pageable pageable = PageRequest.of(
//                pageEntity.getCurrent() -1,
//                pageEntity.getPageSize());
//        Page<ProductManufactDto> page = productManufactInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
//                    List<Predicate> list = new ArrayList<>();
//                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
//                    list.add(pre1);
//                    Predicate pre2 = criteriaBuilder.equal(root.get(ProductManufactInfor_.delete), 0); //过滤为0
//                    list.add(pre2);
//                    Predicate[] p = new Predicate[list.size()];
//                    List<Order> orders = new ArrayList<>();
//                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
//                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
//                        criteriaQuery.orderBy(orders);
//                    } else {
//                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(ProductManufactInfor_.createTime).as(Date.class)));
//                    }
//                    return  criteriaBuilder.and(list.toArray(p));
//                }
//                , pageable);
//        Page<ProductManufactInforEx> page1 = page.map(productManufactInforExMapper::toEntity);
        Page<WorkOrderInforEx> workOrderInforByPage = workOrderInforService.getWorkOrderInforByPage(request, pageEntity);
        Page<Object> productManufactExes = workOrderInforByPage.map(new Function<WorkOrderInforEx, Object>() {

            @Override
            public Object apply(WorkOrderInforEx workOrderInforEx) {
//                if (workOrderInforEx.getReleaseFlag().intValue() == 1) {
//                    return null;
//                }
                System.out.println("workOrderInforEx:" + workOrderInforEx);

                BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(workOrderInforEx.getBatchProductId(), 0);
                if (batchProduct == null) throw new BeadminException("没找到柜体");
                BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
                PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");

                List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndDeleteOrderBySequenceAsc(batchProduct.getProductCode(), 0);
                if (productManufactInfors == null) {
                    return null;
                }
                Float workHourSum = productManufactInforRepository.sumWorkHourByBatchProductIdAndDelete(batchProduct.getId(), 0);
                ProductManufactEx productManufactEx = new ProductManufactEx();
                productManufactEx.setBatchProductId(workOrderInforEx.getBatchProductId());
                productManufactEx.setBatchProductCode(workOrderInforEx.getBatchProductCode());
//                productManufactEx.setBatchProductName(batchProduct.get());
                productManufactEx.setBatchProductType(workOrderInforEx.getProductType());
                productManufactEx.setPlanManufactStartDate(stage.getStagePlanStartTime());
                productManufactEx.setPlanManufactEndDate(stage.getStageEndTime());
                productManufactEx.setStandManufactWorkhour(workHourSum);
                productManufactEx.setChildren(productManufactInforExMapper.toEntity(productManufactInfors));
                productManufactEx.setStatus(workOrderInforEx.getScheduledFlag());
                return productManufactEx;
            }
        });
        return productManufactExes;

    }

    @Override
    public boolean checkPlanDateOut(WorkOrderInfor workOrderInfor) {
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(workOrderInfor.getBatchProductId(), 0);
        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
        PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");

        List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductIdAndDelete(batchProduct.getId(), 0);
        if (productManufactInfors.size() == 0) throw new BeadminException("未找到工序");
        List<String> names = new ArrayList<>();
        for (ProductManufactInfor p :
                productManufactInfors) {
            if (p.getPlanManufactEndDate().after(stage.getStagePlanEndTime())) names.add(p.getProcessName());
        }


        if (names.size() != 0) {
            StringBuilder error = new StringBuilder("工序超时了，请调整工序:[");
            for (String name : names) {
                error.append(name);
                error.append(",");
            }
            error.append("]的时间，请不要超过生产结束时间:["+stage.getStagePlanEndTime()+"]");
            throw new BeadminException(error.toString()); //
        }

        return true;
    }

    /**
     * 更新生产计划的时间-一起更新
     *
     * @param productManufactInforUpdateDtos
     */
    @Override
    public void updateProductManufactInforAll(List<ProductManufactInforUpdateDto> productManufactInforUpdateDtos) {
        if (productManufactInforUpdateDtos == null || productManufactInforUpdateDtos.size() == 0)
            throw new BeadminException("请传入正确的工序执行时间");
        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforUpdateDtos.get(0).getId(), 0);
        if (productManufactInfor == null) throw new BeadminException("未找到工序");
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(productManufactInfor.getBatchProductId(), 0);
        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
        PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");

        List<ProductManufactInfor> productManufactInfors = new ArrayList<>();
        for (ProductManufactInforUpdateDto p : productManufactInforUpdateDtos) {
            if (p.getPlanManufactEndDate().after(stage.getStagePlanEndTime()))
                throw new BeadminException("工序结束时间不能超过批次计划生产结束时间,请调整至" + DateUtil.transDateFormatToString(stage.getStagePlanEndTime()) + "之前");
            ProductManufactInfor productManufactInfor1 = productManufactInforRepository.findProductManufactInforByIdAndDelete(p.getId(), 0);
            if (productManufactInfor1 == null) throw new BeadminException("数据库内工序不全");
            productManufactInfor1.setPlanManufactStartDate(p.getPlanManufactStartDate());
            productManufactInfor1.setPlanManufactEndDate(p.getPlanManufactEndDate());
            System.out.println("productManufactInfor1：" + productManufactInfor1.getPlanManufactEndDate() + productManufactInfor1.getPlanManufactStartDate());

            productManufactInfors.add(productManufactInfor1);
        }
        System.out.println("productManufactInfors的长度：" + productManufactInfors.size());

        productManufactInforRepository.saveAll(productManufactInfors);


        // 记录调整日志
        // 并更新计划产能日历
//        plantCapacityCalendarService.updatePlantCapCalender(batchProduct, batchPlan);
        plantCapacityCalendarService.updatePlantCapCalenderByBatchPlan(batchPlan);
    }

    /**
     * 更新时间
     * @param productManufactDto
     */
    @Override
    public void updateProductManufactTime(ProductManufactDto productManufactDto) {
        if (productManufactDto == null) throw new BeadminException("未传入任何参数！");
        List<ProductManufactInforDto> children = productManufactDto.getChildren();
//        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforUpdateDtos.get(0).getId(),0);
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(productManufactDto.getBatchProductId(), 0);
        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
        List<ProductManufactInfor> productManufactInfors = new ArrayList<>();
        for (ProductManufactInforDto p :
                children) {
//            System.out.println("p:"+p);
            if (p == null) throw new BeadminException("工序" + p.getProcessName() + "为空");
            if (p.getPlanManufactStartDate().after(p.getPlanManufactEndDate()))
                throw new BeadminException("开始时间不能超过结束时间！");
            if (p.getPlanManufactEndDate().after(productManufactDto.getPlanManufactEndDate()))
                throw new BeadminException("工序结束时间不能超过批次计划生产结束时间,请调整至" + DateUtil.transDateFormatToString(productManufactDto.getPlanManufactEndDate()) + "之前");
            ProductManufactInfor productManufactInfor1 = productManufactInforRepository.findProductManufactInforByIdAndDelete(p.getId(), 0);
            if (productManufactInfor1 == null) throw new BeadminException("数据库内工序不全");
            productManufactInfor1.setPlanManufactStartDate(p.getPlanManufactStartDate());
            productManufactInfor1.setPlanManufactEndDate(p.getPlanManufactEndDate());
            System.out.println("productManufactInfor1：" + productManufactInfor1.getPlanManufactEndDate() + productManufactInfor1.getPlanManufactStartDate());
            productManufactInfors.add(productManufactInfor1);
        }
        productManufactInforRepository.saveAll(productManufactInfors);
        // 设置工单排程状态
        workOrderInforService.setWorkOrderScheduledFlag(batchProduct, 2);
        // 记录调整日志
        // 并更新计划产能日历
//        plantCapacityCalendarService.updatePlantCapCalender(batchProduct, batchPlan);
        plantCapacityCalendarService.updatePlantCapCalenderByBatchPlan(batchPlan);

    }


    /**
     * 暂停工序执行 -- 只会暂停当前用户的计时
     *
     * @param request
     * @param productManufactInforId
     * @return
     */
    @Transactional
    @Override
    public int pauseProductManufactExec(HttpServletRequest request, String productManufactInforId) {
        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforId, 0);

        if (productManufactInfor == null) {
            throw new BeadminException("未找到该工序");
        }
        Date d = new Date();
        UserEx userEx = userService.viewBaseInfo(request);
        UserWorkHourInfo userWorkHourInfo = userWorkHourInfoService.getUserWorkHourInfo(userEx, productManufactInforId);
        if (userWorkHourInfo == null) {
            throw new BeadminException("未找到当前用户的计时记录， 请排查 ");
        }

        if (productManufactInfor.getProcessStatus() == 1 && userWorkHourInfo.getProcessStatus() == 1) {
            userWorkHourInfoService.finishTiming(userWorkHourInfo,d);
            userWorkHourInfo.setProcessStatus(2);
            UserWorkHourInfo save = userWorkHourInfoRepository.save(userWorkHourInfo);


//            // 生成实际产能日历
//            plantCapacityCalendarService.updateRealPlantCapCalenderByBatchPlan(productManufactInfor);
//        if ()


            // 暂停计时
            return 0; //  "工序暂停执行";
        } else {
            return -1; //  "工序无法暂停，因为工序处于"+productManufactInfor.getProcessStatus()+"状态";
        }

    }




    /**
     * 根据工单ID获取该工单下的所有生产工序
     *
     * @param woId
     * @return
     */
    @Override
    public List<ProductManufactWorkTimeEx> getProductManufactExecInfosByWoId(String woId) {
        WorkOrderInfor workOrderInfor = workOrderInforRepository.findWorkOrderInforByIdAndDelete(woId, 0);
        if (workOrderInfor == null) {
            throw new BeadminException("请输入正确的工单ID,未查询到该工单ID");
        }
        if (workOrderInfor.getReleaseFlag() != 1) return null;

        List<ProductManufactInforEx> productManufactInfors = workOrderInforService.getManufactInfo(woId);
        List<ProductManufactWorkTimeEx> productManufactExecuteExes = new ArrayList<>();
        productManufactInfors.forEach(new Consumer<ProductManufactInforEx>() {
            @Override
            public void accept(ProductManufactInforEx productManufactInfor) {

                ProductManufactWorkTimeEx productManufactWorkTimeEx = new ProductManufactWorkTimeEx();
                productManufactWorkTimeEx.setWorkOrderInforId(workOrderInfor.getId());
                productManufactWorkTimeEx.setWorkOrderInforCode(workOrderInfor.getWo());
                productManufactWorkTimeEx.setTaskId(productManufactInfor.getId());
                if (productManufactInfor.getManufactEndDate() != null) {
                    productManufactWorkTimeEx.setManufactEndDate(productManufactInfor.getManufactEndDate());
                }
                if (productManufactInfor.getManufactStartDate() != null) {
                    productManufactWorkTimeEx.setManufactStartDate(productManufactInfor.getManufactStartDate());
                }
                if (productManufactInfor.getProcessStatus() != null) {
                    productManufactWorkTimeEx.setProcessStatus(productManufactInfor.getProcessStatus());
                }
                if (productManufactInfor.getProcessErrorFlag().intValue() == 0) {
                    productManufactWorkTimeEx.setTask("正常任务-" + productManufactWorkTimeEx.getWorkOrderInforCode() + "~" + productManufactInfor.getSequence() + "-" + productManufactInfor.getProcessName());
                }
                productManufactExecuteExes.add(productManufactWorkTimeEx);


            }
        });
        return productManufactExecuteExes;
    }

    /**
     * 自动排程
     * @param woId
     */
    @Override
    public void autoScheduleByWoId(String woId) {
        WorkOrderInfor workOrderInfor = workOrderInforService.getWorkOrderInforById(woId);
        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(workOrderInfor.getBatchProductId(), 0);
        if (batchProduct.getIsStandard() == 0 && batchProduct.getIsStdWorkHourUploaded()==0){
            throw new BeadminException(batchProduct.getProductCode()+"工时周期未设置");
        }
        autoScheduleByBatchProduct(batchProduct);
        workOrderInforService.setWorkOrderScheduledFlag(workOrderInfor,2);
    }

    /**
     * 多个工单排程
     * @param woIds
     */
    @Override
    public void autoScheduleByWoIds(List<String> woIds) {
        for (String woId : woIds) {
            autoScheduleByWoId(woId);
        }
    }


    /**
     * 对指定批次自动排程
     *
     * @param batchPlanId
     */
    @Override
    public void autoScheduleByBatchPlanId(String batchPlanId) {
        for (BatchProduct batchProduct : batchProductRepository.findBatchProductByBatchPlanIdAndDelete(batchPlanId, 0)) {
            autoScheduleByBatchProduct(batchProduct);
        }
    }

    /**
     * 对指定柜体自动排程
     *
     * @param batchProduct
     */
    @Override
    public void autoScheduleByBatchProduct(BatchProduct batchProduct) {
        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByIdAndDelete("standard1", 0);

        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProduct.getBatchPlanId(), 0);
        System.out.println("batchPlan" + batchPlan.toString());

        // 直接查询时升序查询
        List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndProcessStatusNotAndDeleteOrderBySequenceAsc(batchProduct.getProductCode(), 0, 0);
        if (productManufactInfors == null) {
            throw new BeadminException("还没有设计工艺路线！");
        }
        for (ProductManufactInfor p :
                productManufactInfors) {
            System.out.println("p:" + p.toString());

        }

        // 第一个工序
        ProductManufactInfor productManufactInfor = productManufactInfors.get(0);
//            BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(bp.getBatchPlanId(), 0);
        PlanStage stage = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产装配");
        productManufactInfor.setPlanManufactStartDate(stage.getStagePlanStartTime());
        System.out.println("productManufactInfor.getPlanManufactStartDate():" + productManufactInfor.getPlanManufactStartDate());
        productManufactInfor.setPlanManufactEndDate(DateUtil.computeDate(productManufactInfor.getPlanManufactStartDate(), Math.round(productManufactInfor.getStandManufactWorkhour())));
        System.out.println("productManufactInfor.getPlanManufactEndDate():" + productManufactInfor.getPlanManufactEndDate());
        productManufactInforRepository.save(productManufactInfor);
        plantCapacityCalendarService.generateCapacityCalendar(productManufactInfor, batchProduct, factoryCalendar, batchPlan);
        // 升序工序的时间
        for (int i = 1; i < productManufactInfors.size(); i++) {
            ProductManufactInfor pmi = productManufactInfors.get(i);
            pmi.setPlanManufactStartDate(productManufactInfors.get(i - 1).getPlanManufactEndDate());
            pmi.setPlanManufactEndDate(DateUtil.computeDate(pmi.getPlanManufactStartDate(), Math.round(pmi.getStandManufactWorkhour())));
            productManufactInforRepository.save(pmi);
            plantCapacityCalendarService.generateCapacityCalendar(pmi, batchProduct, factoryCalendar, batchPlan);
        }

        // 对柜体设置已排程
        batchProduct.setIsPoReleased(1);
        batchProductRepository.save(batchProduct);

    }

    /**
     * 对多个批次批量自动排程
     *
     * @param batchPlanIds
     */
    @Override
    public void autoScheduleByBatchPlanIds(List<String> batchPlanIds) {
        for (String batchPlanId : batchPlanIds) {
            autoScheduleByBatchPlanId(batchPlanId);
        }
    }


    // 校验一下 这些工单是否属于同一批次
    public void checkSameBatchPlan(List<String> woIds) {
        if (ObjectUtil.isEmpty(woIds)) throw new BeadminException("没有选择任何工单");;
        List<String> productIdList = workOrderInforRepository.findBatchProductIdsByWorkOrderInforIdsAndDelete(woIds, 0);
        List<String> list = batchProductRepository.findBatchPlanIdsByBatchProductIdsAndDelete(productIdList, 0);
        if (list.size() > 1) {
            throw new BeadminException("必须选择同一批次的工单");
        }
    }

    /**
     * 变更生产计划
     *
     * @param workOrderProductPlanDto
     */
    @Override
    public void updateProductPlanTime(WorkOrderProductPlanDto workOrderProductPlanDto, boolean isManual) {


        if (workOrderProductPlanDto == null) throw new BeadminException("未传入任何参数！");
        List<ProductPlanTimeDto> productPlanTimeDto = workOrderProductPlanDto.getProductPlanTimeDto();
//        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforUpdateDtos.get(0).getId(),0);
        if (productPlanTimeDto.size() == 0) {
            return;
        }

        productPlanTimeDto.forEach(new Consumer<ProductPlanTimeDto>() {
                                           @Override
            public void accept(ProductPlanTimeDto productPlanTimeDto) {
                int sequence = productManufactInforRepository.findSequenceByIdAndDelete(productPlanTimeDto.getProductManufactInforId(), 0);
                productPlanTimeDto.setSequence(sequence);
            }
        });
        productPlanTimeDto.sort(new Comparator<ProductPlanTimeDto>() {
            @Override
            public int compare(ProductPlanTimeDto o1, ProductPlanTimeDto o2) {
                return o1.getSequence().compareTo(o2.getSequence());
            }
        });

        WorkOrderInfor workOrderInforById = workOrderInforRepository.findWorkOrderInforById(workOrderProductPlanDto.getWoId());
        BatchProduct batchProductByIdAndDelete = batchProductRepository.findBatchProductByIdAndDelete(workOrderInforById.getBatchProductId(), 0);
        List<ProductManufactInfor> productManufactInforBefore = productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndDeleteOrderBySequenceAsc(workOrderInforById.getBatchProductCode(), 0);
//        ProductManufactInfor manufactInfor1 = productManufactInforRepository.findProductManufactInforByIdAndDelete(productPlanTimeDto.get(0).getProductManufactInforId(), 0);
//        BatchProduct batchProduct = batchProductRepository.findBatchProductByIdAndDelete(manufactInfor1.getBatchProductId(), 0);
        BatchPlan batchPlan = batchPlanRepository.findBatchPlanByIdAndDelete(batchProductByIdAndDelete.getBatchPlanId(), 0);
//        batchPlanService.getStageByBatchPlanAndStageName(batchPlan,"生化");
        List<ProductManufactInfor> productManufactInfors = new ArrayList<>();

        PlanStage pick = batchPlanService.getStageByBatchPlanAndStageName(batchPlan, "生产分料");

        ProductPlanTimeDto p0 = productPlanTimeDto.get(0);
        for (int i = 0; i < productPlanTimeDto.size(); i++) {
            ProductPlanTimeDto p = productPlanTimeDto.get(i);
//            System.out.println("p:"+p);
            if (p.getProcessName() == "器件分料"){
                if(p.getPlanManufactStartDate().before(pick.getStagePlanStartTime()))
                    throw new BeadminException(p.getProcessName() + "开始时间不能早于生产分料开始时间！");
            }
            if (p == null) throw new BeadminException("工序" + p.getProcessName() + "为空");
            if (p.getPlanManufactStartDate().after(p.getPlanManufactEndDate()))
                throw new BeadminException(p.getProcessName() + "开始时间不能超过结束时间！");
            if (p.getPlanManufactEndDate().after(batchPlan.getBatchDeliveryDate()))
                throw new BeadminException(p.getProcessName() + "结束时间不能超过批次交付时间,请调整至" + DateUtil.transDateFormatToString(batchPlan.getBatchDeliveryDate()) + "之前");
            if (i != 0) {
                if (p.getPlanManufactStartDate().before(p0.getPlanManufactEndDate()))
                    throw new BeadminException(p.getProcessName()+"开始时间不能早于"+p0.getProcessName()+"结束时间！");
            }

            ProductManufactInfor productManufactInfor1 = new ProductManufactInfor();
            for(ProductManufactInfor InforBefore : productManufactInforBefore){
                if(InforBefore.getProcessName().equals(p.getProcessName())) {
                    productManufactInfor1 = InforBefore;
                    break;
                }
            }

//            ProductManufactInfor productManufactInfor1 = productManufactInforRepository.findProductManufactInforByIdAndDelete(p.getProductManufactInforId(), 0);
            if (productManufactInfor1 == null) throw new BeadminException("数据库内工序不全");
            productManufactInfor1.setPlanManufactStartDate(p.getPlanManufactStartDate());
            productManufactInfor1.setPlanManufactEndDate(p.getPlanManufactEndDate());
            System.out.println("productManufactInfor1：" + productManufactInfor1.getPlanManufactEndDate() + productManufactInfor1.getPlanManufactStartDate());
            productManufactInfors.add(productManufactInfor1);

            p0 = p;
        }
        productManufactInforRepository.saveAll(productManufactInfors);
        // 设置工单排程状态
//        if (isManual) {
//        WorkOrderInfor workOrderInforById = workOrderInforRepository.findWorkOrderInforById(workOrderProductPlanDto.getWoId());
//        BatchProduct batchProductByIdAndDelete = batchProductRepository.findBatchProductByIdAndDelete(workOrderInforById.getBatchProductId(), 0);
        workOrderInforService.setWorkOrderScheduledFlag(batchProductByIdAndDelete, 2);

//        for(ProductPlanTimeDto p : productPlanTimeDto){
//            ProductManufactInfor manufactInfor2 = productManufactInforRepository.findProductManufactInforByIdAndDelete(p.getProductManufactInforId(), 0);
//            BatchProduct batchProduct2 = batchProductRepository.findBatchProductByIdAndDelete(manufactInfor2.getBatchProductId(), 0);
//            workOrderInforService.setWorkOrderScheduledFlag(batchProduct2, 2);
//        }

//        } else {
//            workOrderInforService.setWorkOrderScheduledFlag(batchProduct, 2);
//        }

        // 记录调整日志

        // 并更新计划产能日历
//        plantCapacityCalendarService.updatePlantCapCalender(batchProduct, batchPlan);
        plantCapacityCalendarService.updatePlantCapCalenderByBatchPlan(batchPlan);


    }

    /**
     * 根据工单Id工单下的所有生产排程计划
     *
     * @param woId
     * @return
     */
    @Override
    public List<ProductPlanTimeEx> getProductPlansByWoId(String woId) {
        WorkOrderInfor workOrderInfor = workOrderInforService.getWorkOrderInforById(woId);
        List<ProductPlanTimeEx> productPlanTimeExes = new ArrayList<>();
        for (ProductManufactInfor productManufactInfor : productManufactInforRepository.findProductManufactInforsByBatchProductCodeAndDeleteOrderBySequenceAsc(workOrderInfor.getBatchProductCode(), 0)) {
            ProductPlanTimeEx productPlanTimeEx = new ProductPlanTimeEx();

            productPlanTimeEx.setProductManufactInforId(productManufactInfor.getId());
            productPlanTimeEx.setSequence(productManufactInfor.getSequence());
            productPlanTimeEx.setProcessName(productManufactInfor.getProcessName());
            productPlanTimeEx.setPlanManufactStartDate(productManufactInfor.getPlanManufactStartDate());
            productPlanTimeEx.setPlanManufactEndDate(productManufactInfor.getPlanManufactEndDate());
            productPlanTimeExes.add(productPlanTimeEx);
        }
        return productPlanTimeExes;
    }

    /**
     * 根据id获取生产工序
     *
     * @param processId
     */
    @Override
    public ProductManufactInfor getProductManufactById(String processId) {
        return productManufactInforRepository.findProductManufactInforByIdAndDelete(processId,0);
    }

    @Override
    public int getProductManufactStateById(HttpServletRequest request, String productManufactInforId) {
        UserWorkHourInfo userWorkHourInfo = userWorkHourInfoService.getUserWorkHourInfo(userService.viewBaseInfo(request), productManufactInforId);
        if (userWorkHourInfo == null) {
            return 0;
        }
        return userWorkHourInfo.getProcessStatus();
//        ProductManufactInfor productManufactById = getProductManufactById(productManufactInforId);
//        if (productManufactById == null) {
//            throw new BeadminException("未找到该工序");
//        }
//        return productManufactById.getProcessStatus();
    }

//    */9

    /**
     * 对多个工单排程
     *
     * @param scheduleDto
     */
    @Override
    public void scheduleByWoIds(ScheduleDto scheduleDto, boolean isManual) {
        List<String> woIds = scheduleDto.getWoIds();
        // 检查是否属于同一批次
        checkSameBatchPlan(woIds);
        woIds.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                WorkOrderProductPlanDto workOrderProductPlanDto = new WorkOrderProductPlanDto();
                workOrderProductPlanDto.setWoId(s);
                workOrderProductPlanDto.setProductPlanTimeDto(scheduleDto.getProductPlanTimeDto());
                updateProductPlanTime(workOrderProductPlanDto,isManual);
            }
        });

    }

    /**
     * 获取该工序的实际计时时间(单位:分钟)
     *
     * @param productManufactInforId
     * @return
     */
    @Override
    public float getManuTime(String productManufactInforId) {
        return 0;
    }

    @Override
    public List<String> getProcessNamesByWo(String wo) {
        List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByWorkOrderInforCodeAndDelete(wo , 0);
        List<String> processNames = productManufactInfors.stream().map(ProductManufactInfor::getProcessName).collect(Collectors.toList());
        return processNames;
    }

    public ProductManufactExecuteEx transExecuteInfo(WorkOrderInfor workOrderInfor, ProductManufactInfor dto, UserEx userEx) {
//        if (dto.getProcessStatus() == 3) return null;
        ProductManufactExecuteEx productManufactExecuteEx = new ProductManufactExecuteEx();
        productManufactExecuteEx.setWorkOrderInforCode(workOrderInfor.getWo());
        productManufactExecuteEx.setWorkOrderInforId(workOrderInfor.getId());
        productManufactExecuteEx.setTimeFlag( wrokingHoursOverViewRepository.findTimeFlagByProcessIdAndDelete(dto.getId(), 0));
        if (productManufactExecuteEx.getTimeFlag() == null) productManufactExecuteEx.setTimeFlag(0);
        Integer state = userWorkHourInfoRepository.findStateByProcessIdAndUserIdAndDelete(dto.getId(), userEx.getId(), 0);
        if (state != null) {
            productManufactExecuteEx.setProcessStatus(BigDecimal.valueOf(state));
        }
//        if (productManufactExecuteEx.getProcessStatus() == null) {
//            productManufactExecuteEx.setProcessStatus(0);
//        }
        if (dto.getId() != null) {
            productManufactExecuteEx.setId(dto.getId());
        }
        if (dto.getCreateTime() != null) {
            productManufactExecuteEx.setCreateTime(dto.getCreateTime());
        }
        if (dto.getCreateName() != null) {
            productManufactExecuteEx.setCreateName(dto.getCreateName());
        }
        if (dto.getBatchProductCode() != null) {
            productManufactExecuteEx.setBatchProductCode(dto.getBatchProductCode());
        }
        if (dto.getBatchProductId() != null) {
            productManufactExecuteEx.setBatchProductId(dto.getBatchProductId());
        }
        if (dto.getManufactEndDate() != null) {
            productManufactExecuteEx.setManufactEndDate(dto.getManufactEndDate());
        }
        if (dto.getManufactStartDate() != null) {
            productManufactExecuteEx.setManufactStartDate(dto.getManufactStartDate());
        }
        productManufactExecuteEx.setSequence(dto.getSequence());
        if (dto.getMemo() != null) {
            productManufactExecuteEx.setMemo(dto.getMemo());
        }
        if (dto.getPlanManufactEndDate() != null) {
            productManufactExecuteEx.setPlanManufactEndDate(dto.getPlanManufactEndDate());
        }
        if (dto.getPlanManufactStartDate() != null) {
            productManufactExecuteEx.setPlanManufactStartDate(dto.getPlanManufactStartDate());
        }
        if (dto.getProcessCode() != null) {
            productManufactExecuteEx.setProcessCode(dto.getProcessCode());
        }
        if (dto.getProcessErrorFlag() != null) {
            productManufactExecuteEx.setProcessErrorFlag(BigDecimal.valueOf(dto.getProcessErrorFlag()));
        }
        if (dto.getProcessId() != null) {
            productManufactExecuteEx.setProcessId(dto.getProcessId());
        }
        if (dto.getProcessName() != null) {
            productManufactExecuteEx.setProcessName(dto.getProcessName());
        }
//        if (dto.getProcessStatus() != null) {
//            productManufactExecuteEx.setProcessStatus(BigDecimal.valueOf(dto.getProcessStatus()));
//        }
        if (dto.getIsProductionProcess() != null){
            productManufactExecuteEx.setIsProductionProcess(dto.getIsProductionProcess());
        }
//        assert wrokingHoursOverView != null;
        if (dto.getManufactWorkhour() == null) {
            productManufactExecuteEx.setManufactWorkhour((float) 0);
        } else {
            productManufactExecuteEx.setManufactWorkhour(NumberUtil.roundTwo(dto.getManufactWorkhour() / 3600) );
        }
//        else if (wrokingHoursOverView.getSumWorkHours() != null) {
//
//            productManufactExecuteEx.setManufactWorkhour(DateUtil.transMinToHour(wrokingHoursOverView.getSumWorkHours()));
//        }
        if (dto.getStandManufactWorkhour() != null) {
            productManufactExecuteEx.setStandManufactWorkhour(dto.getStandManufactWorkhour());
        }
        if (productManufactExecuteEx.getProcessStatus() == null) {
            productManufactExecuteEx.setProcessStatus(new BigDecimal(0));
        }
        // 设置预警
        productManufactExecuteEx.setAlertStatus(productManufactExecuteEx.getProcessStatus().intValue());
        dto.setAlertStatus(dto.getProcessStatus());
        if (productManufactExecuteEx.getManufactStartDate() == null) {
            if (new Date().after(productManufactExecuteEx.getPlanManufactStartDate())) {
                productManufactExecuteEx.setAlertStatus(4);
                dto.setAlertStatus(4);
            }
        } else if (productManufactExecuteEx.getManufactStartDate().after(productManufactExecuteEx.getPlanManufactStartDate())) {
            productManufactExecuteEx.setAlertStatus(4);
            dto.setAlertStatus(4);
        }
        if (productManufactExecuteEx.getManufactEndDate() == null) {
            if (new Date().after(productManufactExecuteEx.getPlanManufactStartDate())) {
                productManufactExecuteEx.setAlertStatus(5);
                dto.setAlertStatus(5);
            }
        } else if (productManufactExecuteEx.getManufactEndDate().after(productManufactExecuteEx.getPlanManufactEndDate())) {
            productManufactExecuteEx.setAlertStatus(5);
            dto.setAlertStatus(5);
        }
        productManufactInforRepository.save(dto);
        return productManufactExecuteEx;
    }

    /**
     * 计时开始
     *
     * @param productManufactInforId
     * @return
     */
    @Override
    public int startTiming(String productManufactInforId) {
        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforId, 0);
        if (productManufactInfor == null) {
            throw new BeadminException("未找到该工序");
        }
        if (productManufactInfor.getProcessStatus() != 1) throw new BeadminException("工序未开始执行");
        WrokingHoursOverView wrokingHoursOverView = wrokingHoursOverViewRepository.findWrokingHoursOverViewByProcessIdAndDelete(productManufactInforId, 0);

        WrokingHoursOverView newWHO;

        if (wrokingHoursOverView != null) {
            newWHO = wrokingHoursOverView;
            if (newWHO.getTimeFlag() == 1) {
                return -1;
                //throw new BeadminException("正在计时，请勿再次点击");
            }
            if (newWHO.getTimeFlag() == 2) {
                return -2;
                // throw new BeadminException("计时结束，无法计时");
            }
        } else {
            newWHO = new WrokingHoursOverView();
        }
        newWHO.setCurrStartTime(new Date());
        newWHO.setTimeFlag(1);
        newWHO.setOperatorId("当前用户");  // 把当前用户加进去
        newWHO.setProcessId(productManufactInforId);
        wrokingHoursOverViewRepository.save(newWHO);
        return 0;//"工序计时开始";
    }

    /**
     * 计时暂停
     *
     * @param productManufactInforId
     * @return
     */
    @Override
    public int pauseTiming(String productManufactInforId) {
        ProductManufactInfor productManufactInfor = productManufactInforRepository.findProductManufactInforByIdAndDelete(productManufactInforId, 0);
        if (productManufactInfor == null) {
            throw new BeadminException("未找到该工序");
        }
//        if (productManufactInfor.getProcessStatus() != 1) throw new BeadminException("工序未开始执行");
        WrokingHoursOverView wrokingHoursOverView = wrokingHoursOverViewRepository.findWrokingHoursOverViewByProcessIdAndDelete(productManufactInforId, 0);
        WrokingHoursOverView newWHO;
        if (wrokingHoursOverView != null) { // 已经计时过

            newWHO = wrokingHoursOverView;
            if (newWHO.getTimeFlag() == 0) {
                return -1;
                //throw new BeadminException("计时暂停中，请勿再次暂停");
            }
            if (newWHO.getTimeFlag() == 2) {
                return -2;
                // throw new BeadminException("计时结束，无法计时");
            }

            Date startTime = newWHO.getCurrStartTime();
            Date endTime = new Date();
            Float secondTime = DateUtil.computeDateDuringBySecond(startTime, endTime); // 以秒计算
            newWHO.setTimeFlag(0);
//            newWHO.setOperatorId("当前用户");  // 把当前用户加进去
            newWHO.setProcessId(productManufactInforId);
            newWHO.setAccWorkHours(secondTime);
            if (newWHO.getSumWorkHours() == null) {
                newWHO.setSumWorkHours(secondTime);
            } else {
                newWHO.setSumWorkHours(newWHO.getSumWorkHours() + secondTime);

            }
            wrokingHoursOverViewRepository.save(newWHO);
            WrokingHoursDetailsDto wrokingHoursDetailsDto = new WrokingHoursDetailsDto();
            wrokingHoursDetailsDto.setProcessId(productManufactInforId);
//            wrokingHoursDetailsDto.setOperatorId(productManufactInforId);
            wrokingHoursDetailsDto.setCurrStartTime(newWHO.getCurrStartTime());
            wrokingHoursDetailsDto.setCurrEndTime(endTime);
            wrokingHoursDetailsDto.setCurrDay(DateUtil.transDateFormat(endTime));
            wrokingHoursDetailsDto.setCurrWorkHours(newWHO.getAccWorkHours());
            wrokingHoursDetailsRepository.save(wrokingHoursDetailsMapper.toEntity(wrokingHoursDetailsDto));
            productManufactInfor.setManufactWorkhour(newWHO.getSumWorkHours());
            productManufactInforRepository.save(productManufactInfor);

        } else {
//            throw new BeadminException("还没有开始计时的记录或还未开始计时");
            return 0;
        }


        return 0;//"工序计时暂停";

    }

    /**
     * 分页查询所有生产中的工序
     *
     * @param pageEntity
     * @return
     */
    @Override
    public Page<ProductManufactExecuteEx> getProductManufactInforExecuteByPage(HttpServletRequest request, PageEntity pageEntity) {
        // 如果查询不存在的字段

        UpdateTimeTask updateTimeTask = new UpdateTimeTask();
        taskThreadPool.execute(updateTimeTask);


        if (userService.isAdmin(request)) {

        }
//        List<String> manuList = dictDataService.getDictDataKeyByDictTypeName("生产环节工序");

        // 但是每种角色只能看到指定的工序
        List<String> processNames = new ArrayList<>();
        Set<Role> rolesByCurrentUser = userService.getRolesByCurrentUser(request);
        for (Role role : rolesByCurrentUser) {
            if (role.getCode().equals("ROLE_ManufactManager") || role.getCode().equals("ROLE_ManufactOperator") || role.getCode().equals("ROLE_Admin")) {
                processNames.clear();
                break;
            }
            switch (role.getCode()) {
                case "ROLE_OQC":
                    processNames.add("成品检验");
                    continue;
                case "ROLE_PartsAssembly":
                    processNames.add("零件组装");
                    continue;
                case "ROLE_MaterialSorting":
                    processNames.add("器件分料");
                    continue;
                case "ROLE_ManufactPrepare":
                    processNames.add("生产准备");
                    continue;
                case "ROLE_Wiring":
                    processNames.add("电柜接线");
                    continue;
                case "ROLE_Fitting":
                    processNames.add("装配");
                    continue;
                case "ROLE_Assembly":
                    processNames.add("电柜装配");
                    continue;
                case "ROLE_Testing":
                    processNames.add("电柜测试");
                    continue;
                case "ROLE_Inspector":
                    processNames.add("检验");
                    continue;
                case "ROLE_Package":
                    processNames.add("打包");
                    continue;
                case "ROLE_Lineman":
                    processNames.add("预制线");
                    processNames.add("预制铜排");

            }
        }
        // 当前用户的项目
        List<String> infoIds = infoService.getInfoIdByCurrentUser(request);
        // 当前用户所在项目的所有已经进入生产的柜体
        List<String> batchProductIds = new ArrayList<>();
        if (infoIds == null && !userService.isAdmin(request)) {
            return null;
        } else {
            if (infoIds == null || infoIds.size() == 0) {
                batchProductIds = workOrderInforRepository.findbatchProductByReleaseFlagAndDelete(0, 0);
            } else {
                batchProductIds = workOrderInforRepository.findbatchProductByReleaseFlagAndInfoIdInAndDelete(0, infoIds, 0);
            }
        }


        if (batchProductIds.size() == 0) return null;
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        List<String> finalBatchProductIds = batchProductIds;
//        List<String> finalProcessNames = processNames;
        Page<ProductManufactInfor> page = productManufactInforRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilderNew.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(ProductManufactInfor_.delete), 0); //过滤为0
                    list.add(pre2);
                    //改需求了不用过滤为0的了
//                    Predicate pre3 = criteriaBuilder.equal(root.get(ProductManufactInfor_.isProductionProcess), 1); //过滤为0
//                    list.add(pre3);
//                    Predicate pre3 = criteriaBuilder.in(root.get(ProductManufactInfor_.batchProductId)).value((Expression<? extends String>) batchProductIds);//存入条件集合里
//                    list.add(pre3);
//                    if (batchProductIds.size() != 0 ){
//                    if (!userService.isAdmin(request)) {
                    // 指定柜体ID
                    Path<String> path = root.get(ProductManufactInfor_.batchProductId);
                    CriteriaBuilder.In<String> in = criteriaBuilder.in(path);
                    for (String batchProductId : finalBatchProductIds) in.value(batchProductId);
                    list.add(criteriaBuilder.and(in));

//                    }
                    if (processNames.size() != 0) {
                        // 指定工序
                        Path<String> path2 = root.get(ProductManufactInfor_.processName);
                        CriteriaBuilder.In<String> in2 = criteriaBuilder.in(path2);
                        for (String processName : processNames) in2.value(processName);
                        list.add(criteriaBuilder.and(in2));
                    }


//                    criteriaBuilder.and(in);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(ProductManufactInfor_.createTime).as(Date.class)),criteriaBuilder.asc(root.get(ProductManufactInfor_.sequence).as(Integer.class)));
                    }

                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
//        Page<ProductManufactInforEx> page1 = page.map(productManufactInforExMapper::toEntity);
//        return page1;
        UserEx userEx = userService.viewBaseInfo(request);
        Page<ProductManufactExecuteEx> objects = page.map(new Function<ProductManufactInfor, ProductManufactExecuteEx>() {
            @Override
            public ProductManufactExecuteEx apply(ProductManufactInfor dto) {
                System.out.println("dto:" + dto);
                WorkOrderInfor workOrderInfor = workOrderInforRepository.findWorkOrderInforByBatchProductIdAndDelete(dto.getBatchProductId(), 0);
                if (workOrderInfor == null) {
                    return null;
                }
//                if (workOrderInfor.getReleaseFlag() != 1) return null;


                return transExecuteInfo(workOrderInfor, dto,userEx);

            }
        });

        return objects;
    }

}